/**
 * Copyright (c) 2018-2028, LookAhead.
 * <p>
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.gnu.org/licenses/lgpl.html
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.lookahead.parent.database.base;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.lookahead.parent.apidoc.db.BaseEntity;
import org.lookahead.parent.apidoc.db.Query;
import org.lookahead.parent.apidoc.struct.Kv;
import org.lookahead.parent.common.utils.BeanUtil;
import org.lookahead.parent.common.utils.Func;
import org.lookahead.parent.database.constant.SqlKeyword;

import java.util.List;
import java.util.Map;
import java.util.function.Function;

/**
 * 分页工具
 *
 * @author LookAhead
 */
public class Condition {

    /**
     * 转化成mybatis plus中的Page
     *
     * @param entity 查询条件
     * @return IPage
     */
    public static <T> IPage<T> getPage(BaseEntity entity) {
        Page<T> page = new Page<>(Func.toInt(entity.getCurrent(), 1), Func.toInt(entity.getSize(), 10));
        page.addOrder(OrderItem.ascs(Func.toStrArray(SqlKeyword.filter(entity.getAscs()))));
        page.addOrder(OrderItem.descs(Func.toStrArray(SqlKeyword.filter(entity.getDescs()))));
        return page;
    }

    /**
     * 转化成mybatis plus中的Page
     *
     * @param query 查询条件
     * @return IPage
     */
    public static <T> IPage<T> getPage(Query query) {
        Page<T> page = new Page<>(Func.toInt(query.getCurrent(), 1), Func.toInt(query.getSize(), 10));
        page.addOrder(OrderItem.ascs(Func.toStrArray(SqlKeyword.filter(query.getAscs()))));
        page.addOrder(OrderItem.descs(Func.toStrArray(SqlKeyword.filter(query.getDescs()))));
        return page;
    }

    /**
     * 转化成mybatis plus中的Page
     *
     * @param entity 查询条件
     * @return IPage
     */
    public static <T> Page<T> getPages(BaseEntity entity) {
        Page<T> page = new Page<>(Func.toInt(entity.getCurrent(), 1), Func.toInt(entity.getSize(), 10));
        page.addOrder(OrderItem.ascs(Func.toStrArray(SqlKeyword.filter(entity.getAscs()))));
        page.addOrder(OrderItem.descs(Func.toStrArray(SqlKeyword.filter(entity.getDescs()))));
        return page;
    }

    /**
     * 转化成mybatis plus中的Page
     *
     * @param query 查询条件
     * @return IPage
     */
    public static <T> Page<T> getPages(Query query) {
        Page<T> page = new Page<>(Func.toInt(query.getCurrent(), 1), Func.toInt(query.getSize(), 10));
        page.addOrder(OrderItem.ascs(Func.toStrArray(SqlKeyword.filter(query.getAscs()))));
        page.addOrder(OrderItem.descs(Func.toStrArray(SqlKeyword.filter(query.getDescs()))));
        return page;
    }

    /**
     * 转换Page封装
     *
     * @param oldPage   旧Page封装T
     * @param converter 转换器
     * @return 新Page封装E
     */
    public static <T, E> Page<E> getPage(IPage<T> oldPage, Function<List<T>, List<E>> converter) {
        Page<E> page = new Page<>(oldPage.getCurrent(), oldPage.getSize(), oldPage.getTotal());
        page.setPages(oldPage.getPages());
        page.setRecords(converter.apply(oldPage.getRecords()));
        return page;
    }

    /**
     * 获取mybatis plus中的QueryWrapper
     *
     * @param entity 实体
     * @param <T>    类型
     * @return QueryWrapper
     */
    public static <T> QueryWrapper<T> getQueryWrapper(T entity) {
        return new QueryWrapper<>(entity);
    }

    /**
     * 获取mybatis plus中的QueryWrapper
     *
     * @param query 查询条件
     * @param clazz 实体类
     * @param <T>   类型
     * @return QueryWrapper
     */
    public static <T> QueryWrapper<T> getQueryWrapper(Map<String, Object> query, Class<T> clazz) {
        Kv exclude = Kv.init()
                .set("token", "token")
                .set("current", "current")
                .set("size", "size")
                .set("ascs", "ascs")
                .set("descs", "descs");
        return getQueryWrapper(query, exclude, clazz);
    }

    /**
     * 获取mybatis plus中的QueryWrapper
     *
     * @param query   查询条件
     * @param exclude 排除的查询条件
     * @param clazz   实体类
     * @param <T>     类型
     * @return QueryWrapper
     */
    public static <T> QueryWrapper<T> getQueryWrapper(Map<String, Object> query, Map<String, Object> exclude, Class<T> clazz) {
        exclude.forEach((k, v) -> query.remove(k));
        QueryWrapper<T> qw = new QueryWrapper<>();
        qw.setEntity(BeanUtil.newInstance(clazz));
        SqlKeyword.buildCondition(query, qw);
        return qw;
    }

}
